/**
 * For GLEW on Windows:
 * Link to glew32s (s is for static) and globally #define GLEW_STATIC, this
 * will resolve linker errors to the glew__impl stuff
 */

#include <GL/glew.h>
#include <SDL2/SDL.h>

const char* vertexShaderSource =
        "in vec4 vertex;" \
        "void main() {" \
        "gl_Position = vertex;" \
        "}";

const char* fragmentShaderSource =
        "void main() { gl_FragColor = vec4(0, 0.8, 0.2, 1); }";

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window;
    SDL_Renderer* renderer;
    SDL_CreateWindowAndRenderer(
            640,
            480,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE,
            &window,
            &renderer);

    auto context = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, context);
    SDL_SetWindowTitle(window,
            reinterpret_cast<const char*> (glGetString(GL_VERSION)));

    glewExperimental = true; // for GL functions above 2.0
    if (glewInit() != GLEW_NO_ERROR)
        SDL_SetWindowTitle(window, "GLEW init error");

    GLuint vertexArray;
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    float vertices[] = {
        0.5f, -0.5f, 0.0f,
        0.0f, 0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    auto vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    auto fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    auto program = glCreateProgram();
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glLinkProgram(program);
    glUseProgram(program);

    bool running = true;
    while (running) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT)
                running = false;
            if (event.type == SDL_WINDOWEVENT &&
                    event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
                int w, h;
                SDL_GetWindowSize(window, &w, &h);
                glViewport(0, 0, w, h);
            }
        }
        glClearColor(0.2f, 0.0f, 0.0f, 0.5f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        SDL_GL_SwapWindow(window);
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glDeleteProgram(program);
    SDL_GL_DeleteContext(context);
    SDL_Quit();
    return 0;
}